/*********************************************

**********************************************/
#include <stdio.h>
#include "cc_compat.h"
#include "gpio_smbus.h"
#include "charger.h"
#include "io.h"
#include "io3731.h"

unsigned char return_ack;
unsigned char tdata;


void smbus_init_module(void)
{
	IO_ALT_OUT_DISABLE(GPIO_CHG_SDA);
	IO_ALT_OUT_DISABLE(GPIO_CHG_SCL);
	output_enable_SDA();
	output_enable_SCL();
	input_enable_SDA();
	IO_OPEN_DRAIN_ENABLE(GPIO_CHG_SDA);
	IO_OPEN_DRAIN_ENABLE(GPIO_CHG_SCL);
}

void SMBusSendStart(void)
{
	SMBusClkHigh();
	SMBusDatHigh();
	SMBusDatLow();
}

//host send 8-bit data to device and then check ACK
unsigned char SMBusPassByte(unsigned char bData)
{
	unsigned char i=9;
	unsigned char smbus_ack;

	while (--i)
	{
		SMBusClkLow();

		if ((bData)&0x80)
			SMBusDatHigh();
		else
			SMBusDatLow();

		SMBusClkHigh();
		bData<<=1;
	}
	//check ACK
	SMBusClkLow();
	SMBusDatHigh();
//release SMBus_DAT, wait device's ACK

	SMBusClkHigh();
	smbus_ack = read_SDA();

	for (i=0; i++; i<10)
	{
		if (smbus_ack == 0)	//got ack
			break;
		else
			smbus_ack = read_SDA();
	}

	SMBusClkLow();

	return smbus_ack;
}

// receive 8-bit data from device and then send ACK
unsigned char SMBusTakeByte(unsigned char nACK)
{
	unsigned char i=9;

	SMBusDatHigh();		//release SMBus_DAT

	tdata = 0;
	input_enable_SDA();
	while (--i)
	{
		tdata <<= 1;
		SMBusClkHigh();
		tdata |= read_SDA();
		SMBusClkLow();
	}

	//NACK
	if (nACK == 1)
	{
		SMBusClkLow();
		SMBusDatHigh();
		SMBusClkHigh();
	}
	else 		// ack
	{
		SMBusDatLow();
		SMBusClkLow();

		SMBusClkHigh();

		SMBusClkLow();
		SMBusDatHigh();
	}

	return tdata;
}
void SMBusSendStop(void)
{
	SMBusClkLow();
	SMBusDatLow();
	SMBusClkHigh();
	SMBusDatHigh();
}

unsigned char Write_Charger(unsigned char REG_index,unsigned int REG_data)
{
	return_ack = WITH_ACK;

	SMBusSendStart();		//Start bit

	return_ack = SMBusPassByte(Charger_Addr_W);
	if (return_ack == WITHOUT_ACK) return SMB_ACK_TIMEOUT;

	return_ack = SMBusPassByte(REG_index);
	if (return_ack == WITHOUT_ACK) return SMB_ACK_TIMEOUT;

	return_ack = SMBusPassByte(REG_data & 0x00FF);
	if (return_ack == WITHOUT_ACK) return SMB_ACK_TIMEOUT;

	return_ack = SMBusPassByte(REG_data >> 8);
	if (return_ack == WITHOUT_ACK) return SMB_ACK_TIMEOUT;

	SMBusSendStop();	    //Stop bit

	return return_ack;
}

unsigned int Read_Charger(unsigned char REG_index)
{
	unsigned int tmp;

	SMBusSendStart();	    //Start bit

	return_ack = SMBusPassByte(Charger_Addr_W); //0:got ack ; 1: NO ack
	if (return_ack == WITHOUT_ACK) return SMB_ACK_TIMEOUT;

	return_ack = SMBusPassByte(REG_index);
	if (return_ack == WITHOUT_ACK) return SMB_ACK_TIMEOUT;


	SMBusSendStop();    	//Stop bit
	SMBusSendStart();	    //Start bit

	return_ack = SMBusPassByte(Charger_Addr_R);
	if (return_ack == WITHOUT_ACK) return SMB_ACK_TIMEOUT;

	//Receive data of device
	tmp = SMBusTakeByte(WITH_ACK);
	tmp |= (int)SMBusTakeByte(WITHOUT_ACK) << 8 ;

	SMBusSendStop();	    //Stop bit

	return tmp;
}


